package com.compass.mobile.network.flow
import com.compass.mobile.network.error.ApiException
import com.compass.mobile.network.error.ERROR
import com.compass.mobile.network.error.ExceptionHandler
import com.compass.mobile.network.response.BaseResponse

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.withTimeout


/**
 * @desc   flow请求拓展
 * @param errorBlock 错误回调
 * @param requestCall 执行的请求
 * @param loadingBlock 开启和关闭加载框
 * @return 请求结果
 */
suspend fun <T> requestFlow(
    errorBlock: ((Int?, String?) -> Unit)? = null,
    requestCall: suspend () -> BaseResponse<T>?,
    loadingBlock: ((Boolean) -> Unit)? = null
): T? {
    var data: T? = null
    val flow = flow {
        //设置超时时间
        val response = withTimeout(60 * 1000) {
            requestCall()
        }

        if (response?.isFailed() == true) {
            response.msg?.let {
                throw ApiException(response.code, it)
            }?:kotlin.run {
                throw ApiException(response.code, ERROR.NOT_FOUND.errMsg)
            }
        }
        //2.发送网络请求结果回调
        emit(response)
        //3.指定运行的线程，flow {}执行的线程
    }.flowOn(Dispatchers.IO)
        .onStart {
            //4.请求开始，展示加载框
            loadingBlock?.invoke(true)
        }
        //5.捕获异常
        .catch { e ->
            e.printStackTrace()
            LogUtil.e(e)
            val exception = ExceptionHandler.handleException(e)
            errorBlock?.invoke(exception.errCode, exception.errMsg)
        }
        //6.请求完成，包括成功和失败
        .onCompletion {
            loadingBlock?.invoke(false)
        }
    //7.调用collect获取emit()回调的结果，就是请求最后的结果
    flow.collect {
        data = it?.data
    }
    return data
}




